package edu.pku.sei.modeler.neditor.part;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.PolylineDecoration;
import org.eclipse.draw2d.RotatableDecoration;
import org.eclipse.draw2d.XYAnchor;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.ui.views.properties.IPropertySource;

import edu.pku.sei.gefcommon.descriptor.core.PropertyDescriptorAdapter;
import edu.pku.sei.modeler.model.core.MetaModelElement;
import edu.pku.sei.modeler.model.notation.core.ShapeConstance;
import edu.pku.sei.modeler.model.notation.core.ShapeNode;
import edu.pku.sei.modeler.model.notation.shape.ConnectionTemplate;

public class ConnectionEditPart extends AbstractConnectionEditPart implements
PropertyChangeListener {
	public void activate() {
        super.activate();
        ((MetaModelElement) getModel()).addPropertyChangeListener(this);
    }

    public void deactivate() {
        super.deactivate();
        ((MetaModelElement) getModel()).removePropertyChangeListener(this);
    }
    public Object getAdapter(Class key) {
		if (IPropertySource.class == key) {
			Object model = getModel();
			if(model instanceof ShapeNode){
				return new PropertyDescriptorAdapter((MetaModelElement)model);
			}
		}
		return super.getAdapter(key);
	}
    public void propertyChange(PropertyChangeEvent evt) {
		String type = evt.getPropertyName();
		if(type==ShapeConstance.REFRESH_ALL){
			this.refreshVisuals();
		} else if(type==ShapeConstance.REFRESH_VIEW){
			this.refreshVisuals();
		}
	}

	protected IFigure createFigure(){
		/*org.eclipse.draw2d.PolylineConnection c = new org.eclipse.draw2d.PolylineConnection();
		org.eclipse.draw2d.RectangleFigure r= new org.eclipse.draw2d.RectangleFigure();
		org.eclipse.draw2d.EllipseAnchor*/
		org.eclipse.draw2d.PolylineConnection c = new org.eclipse.draw2d.PolylineConnection();
		//c.setSourceAnchor(new XYAnchor(new Point(100,100)));
		//c.setTargetAnchor(new XYAnchor(new Point(200,100)));
		
		return c;
	}
	public void setSelected(int value) {
        super.setSelected(value);
        if (value != EditPart.SELECTED_NONE)
            ((PolylineConnection) getFigure()).setLineWidth(2);
        else
            ((PolylineConnection) getFigure()).setLineWidth(1);
    }
	
	RotatableDecoration createDecoration(int endStyle)
	{
		if(endStyle == ConnectionTemplate.END_ARROW) {
			PolylineDecoration decoration = new PolylineDecoration();
			decoration.setScale(10, 5);
			return decoration;
		}
		else if(endStyle == ConnectionTemplate.END_TRIANGLE) {
			PolygonDecoration decoration = new PolygonDecoration();
			decoration.setScale(10, 5);
			decoration.setBackgroundColor(ColorConstants.white);
			return decoration;
		}
		else if(endStyle == ConnectionTemplate.END_DIAMOND) {
			PolygonDecoration decoration = new PolygonDecoration();
			PointList points = new PointList();
			points.addPoint(0, 0);
			points.addPoint(-1, -1);
			points.addPoint(-2, 0);
			points.addPoint(-1, 1);
			decoration.setTemplate(points);
			decoration.setScale(10, 5);
			decoration.setBackgroundColor(ColorConstants.white);
			return decoration;
		}
		else if (endStyle == ConnectionTemplate.END_SOLIDTRIANGLE) {
			PolygonDecoration decoration = new PolygonDecoration();
			decoration.setScale(10, 5);
			decoration.setBackgroundColor(ColorConstants.black);
			return decoration;
		}
		else if (endStyle == ConnectionTemplate.END_SOLIDDIAMOND) {
			PolygonDecoration decoration = new PolygonDecoration();
			PointList points = new PointList();
			points.addPoint(0, 0);
			points.addPoint(-1, -1);
			points.addPoint(-2, 0);
			points.addPoint(-1, 1);
			decoration.setTemplate(points);
			decoration.setScale(10, 5);
			decoration.setBackgroundColor(ColorConstants.black);
			return decoration;
		}
		else return null;
	}
	protected void refreshVisuals(){
		PolylineConnection figure = (PolylineConnection)getFigure();
		ConnectionTemplate model = (ConnectionTemplate)getModel();
		XYAnchor anchor = null;
		
		figure.setLineStyle(model.getLineStyle());
		figure.setTargetDecoration(createDecoration(model.getEndStyle()));
		
		anchor = (XYAnchor)figure.getSourceAnchor();
		anchor.setLocation(model.getStartPoint());
		anchor = (XYAnchor)figure.getTargetAnchor();
		anchor.setLocation(model.getEndPoint());
		
	}
	@Override
	protected void createEditPolicies() {
		// TODO Auto-generated method stub
		installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, new ConnectionEndpointEditPolicy());
	}
}
